<template>
  <el-upload
      v-model:file-list="fileList"
      list-type="picture-card"
      :multiple="props.multiple"
      :limit="props.imageLimit"
      :before-upload="beforeUpload"
      :http-request="httpRequest"
      :on-exceed="handleExceed"
      :on-remove="handleRemove">
    <el-icon><Plus /></el-icon>
  </el-upload>
</template>

<script lang="ts" setup>
import { defineModel, defineProps, PropType, computed, watch, ref } from 'vue'
import { Plus } from '@element-plus/icons-vue'
import { ElMessage, UploadFile, UploadProps, UploadRawFile, UploadRequestOptions, UploadUserFile } from 'element-plus'
import { checkUploadFile, doUploadFile } from '@/utils/fileUtil'

const imageData = defineModel({
  required: true,
  type: [Array, String] as PropType<string | string[]>
})

const props = defineProps({
  imagePath: {
    required: true,
    type: String
  },
  multiple: {
    default: false,
    type: Boolean
  },
  imageLimit: {
    default: 3,
    type: Number
  },
  isCompress: {
    default: true,
    type: Boolean
  },
  serviceFileRootPath: {
    required: true,
    type: String
  },
  serviceUrl: {
    required: true,
    type: String
  }
})

const imageList = computed(() => {
  return Array.isArray(imageData.value) ? imageData.value : [imageData.value]
})

const fileList = ref<UploadUserFile[]>([])

const updateImageList = () => {
  fileList.value = []
  imageList.value.forEach((item) => {
    if (item) {
      fileList.value.push({
        name: 'image',
        url: `${props.serviceFileRootPath}${item}`
      })
    }
  })
}

watch(() => imageList.value, () => {
  updateImageList()
}, {
  immediate: true
})

const imageTypeList = ['image/jpeg', 'image/png']

const beforeUpload: UploadProps['beforeUpload'] = (rawFile: UploadRawFile) => {
  return checkUploadFile(rawFile, imageTypeList, '图片')
}

/**
 * 上传请求
 * @param options 选项
 */
const httpRequest: UploadProps['httpRequest'] = async (options: UploadRequestOptions): Promise<any> => {
  if (imageList.value.length > props.imageLimit) {
    return
  }

  const url = props.serviceUrl as string
  const path = props.imagePath as string
  const result = await doUploadFile(url, options.file, path, <boolean>props.isCompress)

  if (Array.isArray(imageData.value)) {
    imageData.value.push(result.url)
  } else {
    imageData.value = result.url
  }
}

const handleExceed: UploadProps['onExceed'] = () => {
  ElMessage.warning(`最多上传${props.imageLimit}张照片`)
}

/**
 * 删除文件
 * @param uploadFile 上传文件
 */
const handleRemove: UploadProps['onRemove'] = (uploadFile: UploadFile) => {
  if (Array.isArray(imageData.value)) {
    const index = fileList.value.findIndex((value) => uploadFile.uid === value.uid)
    imageData.value.splice(index, 1)
  } else {
    imageData.value = ''
  }
}
</script>
